package com.fdb.efp.batch.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.fdb.basic.framework.core.base.FrameworkService;
import com.fdb.basic.framework.core.constant.MonAlrmLvlEnums.MonAlrmLvlEnum;
import com.fdb.basic.framework.core.util.DateTool;
import com.fdb.basic.framework.core.util.SFTPUtil;
import com.fdb.basic.framework.core.util.ZipUtil;
import com.fdb.efp.batch.service.facade.AccFileAnalysisService;
import com.fdb.efp.loan.service.facade.AccoutErroTempService;
import com.fdb.efp.loan.service.vo.AccoutErroTempVO;
import com.jcraft.jsch.ChannelSftp;

/**
 * 
 * 交互文件服务-同步文件解析
 * 
 * @author ludayong
 * @since 2019年1月9日 上午9:09:16
 * @version 1.0
 */
@Service("accFileAnalysisService")
public class AccFileAnalysisServiceImpl implements AccFileAnalysisService, FrameworkService {

	private static Logger logger = LoggerFactory.getLogger(AccFileAnalysisServiceImpl.class);

	@Value("${analysis.accFilePath}")
	private String accFilePath;// 同步文件解析路径

	@Value("${file.remoteDownAccfilePath}")
	private String remoteDownAccfilePath;// 前置文件服务器：下载地址

	@Value("${analysis.hjFtpHost}")
	private String hjFtpHost;// 前置文件服务器IP地址

	@Value("${analysis.hjUserName}")
	private String hjUserName;// 前置文件服务器用户名

	@Value("${analysis.hjPassword}")
	private String hjPassword;// 前置文件服务器登录密码

	@Value("${analysis.hjFtpPort}")
	private int hjFtpPort;// 前置文件服务器端口号

	private static String CTRL_SUFFIX = ".ctrl";// ok文件后缀

	@Autowired
	@Qualifier("accoutErroTempService")
	private AccoutErroTempService accoutErroTempService;// 同步文件记录异常信息
	
	/**
	 * 
	 * 交互文件服务-并账文件解析
	 * 
	 * @return boolean
	 * @throws Exception
	 * @author ludayong
	 * @since 2019年1月9日 上午9:09:16
	 * @version 1.0
	 */
	@Override
	public boolean analysisFile() throws Exception {
		boolean fileDownRes = downloadFile();// 前置文件服务器下载文件
		boolean result = false;
		// 1、解压同步文件		
		logger.info("1、解压同步文件,同步文件解析路径accFilePath"+accFilePath);
		File files = new File(accFilePath);// 解析文件
		if (fileDownRes && files.exists()) {
			File[] accFiles = files.listFiles();
			if (accFiles.length > 0) {
				for (File accFile : accFiles) {
					if (accFile.getName().endsWith(ZipUtil.EXT)) {// 同步文件
						// 校验ok文件是否存在
						logger.info("校验ok文件是否存在");
						File okFile = new File(accFile.getAbsolutePath().replace(ZipUtil.EXT, CTRL_SUFFIX));
						if (okFile.exists()) {
							try {
								// 1、解压同步文件
								logger.info("校验ok文件存在,解压同步文件开始");
								result = ZipUtil.unZipAll(new File(accFile.getAbsolutePath()),
										new File(accFile.getAbsolutePath().replace(ZipUtil.EXT, "")));
								logger.info("校验ok文件存在,解压同步文件结束"+result);
							} catch (IOException e) {
								logger.error("交互文件服务-并账文件解压出现异常，异常信息" + e.getMessage());
								e.printStackTrace();
								throw new IOException();
							}
						}
					}
				}
			}

		}
		return result;
	}

	/**
	 * 从前置文件服务器下载文件
	 * 
	 * @return
	 * @throws Exception
	 * @author ludayong
	 * @since 2019年1月15日 上午8:54:23
	 * @version 1.0
	 */
	private boolean downloadFile() throws Exception {
		// 连接前置文件服务器
		SFTPUtil sftpUtil = null;
		boolean fileDownRes = false;// 下载文件是否成功
		int downTotal = 0;
		try {
			// 从前置文件服务器下载文件到本地
			logger.info("从前置文件服务器信息："+hjUserName+" / "+hjPassword+" IP: "+ hjFtpHost+" 端口号："+hjFtpPort);
			logger.info("从前置文件服务器下载文件到本地");			
			sftpUtil = new SFTPUtil(hjUserName, hjPassword, hjFtpHost, hjFtpPort);			
			// 检测解析目录是否有需要解析的文件存在
			logger.info("检测解析目录是否有需要解析的文件存在，remoteDownAccfilePath前置文件服务器：下载地址"+remoteDownAccfilePath);		
			Vector<ChannelSftp.LsEntry> files = sftpUtil.ls(remoteDownAccfilePath);
			Objects.requireNonNull(files);// 文件不允许为空

			for (ChannelSftp.LsEntry file : files) {
				String fileName = file.getFilename();// 下载文件名
				logger.info("下载文件名"+file.getFilename());	
				if (".".equals(fileName) || "..".equals(fileName)) {
					continue;
				} else {
					try {
						boolean singleFileDownRes = sftpUtil.downFile(sftpUtil, remoteDownAccfilePath, file.getFilename(), accFilePath,
								file.getFilename(), false);
						logger.info("前置文件服务器下载文件：" + remoteDownAccfilePath + file.getFilename() + "，结果[" + singleFileDownRes + "]");
						if (singleFileDownRes) {
							downTotal++;// 下载文件数
						}
					} catch (Exception e) {
						e.printStackTrace();
						String tableName = "";
						String errorMsg = "前置文件服务器下载文件出现异常：" + e.getMessage();
						logger.error(errorMsg);
						// 记录异常信息
						this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
					}
				}
			}
			if (downTotal > 0) {// 下载文件数大于0，则解析
				fileDownRes = true;
			}
			logger.info("本次前置文件服务器下载文件数目：[" + downTotal + "]");
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "";
			String errorMsg = "前置文件服务器下载文件出现异常：" + e.getMessage();
			logger.error(errorMsg);
			// 记录异常信息
			this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, errorMsg);
		} finally {
			if (sftpUtil != null) {
				sftpUtil.closeSFTP();
			}
		}
		return fileDownRes;
	}
	
	/**
	 * 
	 * 记录异常信息 <br>
	 * 0.1:ludayong:2019年3月8日 上午8:40:46:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月8日 上午8:40:46
	 * @date 2019年3月8日 上午8:40:46
	 * @version 0.1
	 */
	private void addErrorInfo(String tableName, String errorType, String errorMsg, String remark) {
		AccoutErroTempVO accoutErroTempVO = new AccoutErroTempVO();
		// 表名
		accoutErroTempVO.setTableName(tableName);
		// 错误级别
		accoutErroTempVO.setErroType(errorType);
		// 错误信息
		accoutErroTempVO.setErroMsg(errorMsg);
		// 备注
		accoutErroTempVO.setRemark(remark);
		// 创建时间
		accoutErroTempVO.setCreateData(DateTool.getCurrentDateTime());
		// 修改时间
		accoutErroTempVO.setLastModifyTime(DateTool.getCurrentDateTime());
		// 记录异常信息
		accoutErroTempService.insert(accoutErroTempVO);
	}
}
